﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OntologyCache;
using biolit_config;
using System.IO;
using System.Collections;
using System.Xml.Linq;

namespace UCSD_BioLit
{
    
    public partial class BioLitTaskPane : UserControl
    {
        public BioLitTaskPane()
        {
            InitializeComponent();
        }

        public void TestFlow()
        {
            
        }



        public void BuildAllOntologies()
        {

        }


        public void ShowTermTree(string OntologyTerm)
        {

        }

        private void txtBoxSearch_Enter(object sender, EventArgs e)
        {
            
        }

        public void BuildOntologyTree(string OntologyName)
        {
            
        }

        private void /*TreeNode*/ RecursiveAdd(OntologyCache.OntologyNode on, TreeNode tn)
        {
            if (on.Children.Count == 0)
            {
                return;
                
            }
            foreach (OntologyNode child in on.Children)
            {
                TreeNode tCur = tn.Nodes.Add(child.Name);
                tCur.Tag = child;
                RecursiveAdd(child, tCur);
                
            }
            //return tCur;
        }

        

        private void OnNodeSelected(object sender, TreeViewEventArgs e)
        {
                OntologyNode on = (OntologyNode)e.Node.Tag;
                if (on != null)
                {
                    txtOntoBrowserTermInfo.Text = "ID : " + on.id + "   " + on.Definition;
                }
        }

        private void OnDropDown(object sender, EventArgs e)
        {
            this.comboOntologies.Items.Clear();
            int Count = Globals.ThisAddIn.m_SelectedOntologies.Count;

            this.comboOntologies.Items.Add("Select an Ontology");
            this.comboOntologies.SelectedItem = this.comboOntologies.Items[0];
            this.comboOntologies.SelectedIndex = 0;

            for (int i = 0; i < Count; ++i)
            {
                this.comboOntologies.Items.Add(Globals.ThisAddIn.m_SelectedOntologies[i].Name);
            }
        }

        private void OnOntologySelected(object sender, EventArgs e)
        {
            tvOntoBrowser.Nodes.Clear();
                foreach (OntologyCache.OntologyInfo OntInfo in Globals.ThisAddIn.m_Ontologies)
                {
                    if (OntInfo.OntologyName == (string)this.comboOntologies.SelectedItem)
                    {
                        this.tvOntoBrowser.Nodes.Clear();
                        foreach (var Item in OntInfo.m_OntologyTree)
                        {
                            OntologyCache.OntologyNode on = (OntologyCache.OntologyNode)Item.Value;
                            if (on.IsTopLevelNode == true)
                            {
                                    TreeNode tn = tvOntoBrowser.Nodes.Add(on.Name);
                                    tn.Tag = on;
                                    if (on.Children.Count > 0)
                                    {
                                        RecursiveAdd(on, tn);
                                    }
                            }
                        }
                    }
                }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            /*OntologyNode on = (OntologyNode)e.Node.Tag;
            if (on != null)
            {
                this.lblOntNameVal.Text = on.OntologyName;
                this.txtBoxOntologyDescription.Text = on.Definition;
                
            }
            */
        }

        private void OnOntologySearchKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                string Text = this.txtBoxOntTerm.Text;
                InternalLookup(Text);

            }       
        }

        private void PathToRoot(Dictionary<string,OntologyNode> lookup, OntologyCache.OntologyNode node, TreeNodeCollection tc)
        {
            List<OntologyNode> Path = new List<OntologyNode>();
            Path.Insert(0, node);
            while (true)
            {
                if (node.isaName == null || node.isaName == "" || (false == lookup.ContainsKey(node.isaName) ) )
                {
                    break;
                }
                node = lookup[node.isaName];
                Path.Insert(0, node);
            }

            
            TreeNode LastNode = null;
            foreach (OntologyNode on in Path)
            {
                TreeNode tn = new TreeNode();
                tn.Tag = on;
                tn.Text = on.Name;
                tc.Add(tn);
                tc = tn.Nodes;
                LastNode = tn;
               
            }
            this.tvOntTermAncestry.ExpandAll();
            LastNode.ForeColor = Color.Blue;


            
            
        }

        private void tabPage2_Click(object sender, EventArgs e)
        {
         
        }


        internal void InternalLookup(string p)
        {
            this.tvOntTermAncestry.Nodes.Clear();

            this.txtBoxOntologyDescription.Text = string.Empty;

            foreach (OntologyCache.OntologyInfo OntInfo in Globals.ThisAddIn.m_Ontologies)
            {
                if (OntInfo.m_TermLookup.ContainsKey(p))
                {
                    string s = OntInfo.OntologyName + " Ontology";
                    
                    TreeNode tn = this.tvOntTermAncestry.Nodes.Add(s.ToUpper());
                    tn.ForeColor = Color.Orange;                
                    PathToRoot(OntInfo.m_TermLookup, OntInfo.m_TermLookup[p],tn.Nodes);
                }
                
            }

            if (tvOntTermAncestry.Nodes.Count == 0)
            {
                // no results found, lets check against a different capitalization
                string lowerCaseVersion = p.ToLower();
                string newVersion = string.Empty;

                if (p.Length > 0 && p.Equals(lowerCaseVersion))
                {
                    // create the upper case version
                    char[] upperCaseVersion = new char[p.Length];
                    string firstLetterInCapitals = p[0].ToString().ToUpper();

                    upperCaseVersion[0] = firstLetterInCapitals[0];

                    if (p.Length > 1)
                    {
                       p.CopyTo(1, upperCaseVersion, 1, p.Length - 1);
                    }

                    newVersion = new string(upperCaseVersion);
                } else{
                    newVersion = lowerCaseVersion;
                }

                if (newVersion.Length > 0)
                {
                    // let's try do a search with different capitalization
                    foreach (OntologyCache.OntologyInfo OntInfo in Globals.ThisAddIn.m_Ontologies)
                    {
                        if (OntInfo.m_TermLookup.ContainsKey(newVersion))
                        {
                            string s = OntInfo.OntologyName + " Ontology";

                            TreeNode tn = this.tvOntTermAncestry.Nodes.Add(s.ToUpper());
                            tn.ForeColor = Color.Orange;
                            PathToRoot(OntInfo.m_TermLookup, OntInfo.m_TermLookup[newVersion], tn.Nodes);
                        }
                    }
                }

                if (tvOntTermAncestry.Nodes.Count == 0)
                {
                    // none found still, so let's display a message to the user
                    TreeNode tn = this.tvOntTermAncestry.Nodes.Add("No results found");
                }
            }
        }

        internal void LookupTerm(string p)
        {
            this.BrowserTab.SelectedIndex = 0;
            this.txtBoxOntTerm.Text = p;
            InternalLookup(p);
            
        }

        private void txtBoxOntologyDescription_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnMarkupApply_Click(object sender, EventArgs e)
        {
            TreeNode tn = this.tvOntoBrowser.SelectedNode;
            if (tn != null)
            {
                OntologyNode on = (OntologyNode)tn.Tag;
                if (on != null)
                {
                    if (Globals.ThisAddIn.Application.Selection.Range != null)
                    {
                        WordCommonFuncs.OntologyMarkup(Globals.ThisAddIn.Application.Selection.Range, Convert.ToString(SmartTagHandlers.GetOntologyID(on.OntologyName)), on.id, on.OntologyName, on.OntologyName);
                    }
                }
            }
            
        }

        protected override void OnResize(EventArgs e)
        {
            if (this.Width > 0)
            {
                int theWidth = this.Width - 10;

                this.BrowserTab.Width = theWidth;
                this.BrowserTab.Height = this.Height;


                this.tvOntoBrowser.Width = theWidth - 15;
                this.tvOntoBrowser.Height = (this.Height / 10) * 6;

                this.comboOntologies.Width = theWidth - 15;
                this.btnMarkupApply.Width = theWidth - 15;

                txtOntoBrowserTermInfo.Bounds = new Rectangle(tvOntoBrowser.Left, tvOntoBrowser.Top + tvOntoBrowser.Height + 10, theWidth - 15, this.tvOntoBrowser.Height / 4);


                this.tvOntTermAncestry.Width = this.tvOntoBrowser.Width;
                this.tvOntTermAncestry.Height = this.tvOntoBrowser.Height;

                this.txtBoxOntologyDescription.Bounds = new Rectangle(tvOntTermAncestry.Left, tvOntTermAncestry.Top + tvOntTermAncestry.Height + 10, theWidth - 15, tvOntTermAncestry.Height / 4);

                this.txtBoxOntTerm.Width = theWidth - 15;
            }


            base.OnResize(e);
        }

        private void txtOntoBrowserTermInfo_TextChanged(object sender, EventArgs e)
        {

        }
    }
    
    
}